package com.internetCafes.spms.web.tenant.controller;

import com.internetCafes.spms.common.CommonConstants;
import com.internetCafes.spms.common.module.excel.ExcelUtils;
import com.internetCafes.spms.common.module.excel.po.OrgInfoExcel;
import com.internetCafes.spms.common.module.excel.po.OrgInfoExportExcel;
import com.internetCafes.spms.common.utils.ExcelImportUtil;
import com.internetCafes.spms.common.utils.ShiroUtils;
import com.internetCafes.spms.core.annotation.SysLog;
import com.internetCafes.spms.core.exception.RRException;
import com.internetCafes.spms.core.model.pageModel.DataGrid;
import com.internetCafes.spms.core.utils.FileUtils;
import com.internetCafes.spms.core.utils.IdWorker;
import com.internetCafes.spms.core.utils.Query;
import com.internetCafes.spms.core.utils.R;
import com.internetCafes.spms.web.sys.form.SysRegisterForm;
import com.internetCafes.spms.web.sys.model.ConfInfo;
import com.internetCafes.spms.web.sys.model.ResourceInfo;
import com.internetCafes.spms.web.sys.model.UserInfo;
import com.internetCafes.spms.web.sys.service.ConfInfoService;
import com.internetCafes.spms.web.sys.service.ResourceInfoService;
import com.internetCafes.spms.web.sys.service.UserInfoService;
import com.internetCafes.spms.web.sys.vo.ConfInfoVo;
import com.internetCafes.spms.web.sys.vo.ResourceInfoVo;
import com.internetCafes.spms.web.tenant.model.TenantCertiInfo;
import com.internetCafes.spms.web.tenant.model.TenantInfo;
import com.internetCafes.spms.web.tenant.service.TenantCertiInfoService;
import com.internetCafes.spms.web.tenant.service.TenantInfoService;
import com.internetCafes.spms.web.tenant.vo.TenantInfoVo;
import com.sms.common.util.hutool.core.util.ObjectUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecgframework.poi.excel.entity.ImportSheetParams;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 租户信息表
 *
 * @author Sunny
 * @email rekeeper2011@hotmail.com
 * @date 2019-10-31 18:09:54
 */
@RestController
@RequestMapping("/tenant/tenantInfo")
public class TenantInfoController {

    @Autowired
    private TenantInfoService tenantInfoService;

    @Autowired
    private ConfInfoService confInfoService;

    @Autowired
    private ResourceInfoService resourceInfoService;

    @Autowired
    private TenantCertiInfoService tenantCertiInfoService;

    @Autowired
    private UserInfoService userInfoService;

    @Value("${system.upload.video}")
    private String videoPath;

    @Value("${system.upload.pic}")
    private String picPath;

    @Value("${system.remote.url}")
    private String remoteUrl;

    @Value("${system.upload.basePath}")
    private String basePath;

    @Value("${system.upload.others}")
    private String othersPath;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    /**
     * 列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("tenant:tenantInfo:list")
    public R list(@RequestParam Map<String, Object> params) {

        //查询列表数据
        Query query = new Query(params);

        DataGrid dataGrid = tenantInfoService.dataGrid(params, query.getPage(), query.getLimit());

        return R.ok().put("page", dataGrid);
    }


    /**
     * 根据ID获取数据
     */
    @RequestMapping("/info/{id}")
    @RequiresPermissions("tenant:tenantInfo:info")
    public R info(@PathVariable("id") Long id) {
        if (id == null || id == 0) {
            id = ShiroUtils.getUserEntity().getDeptId();
        }
        TenantInfo t = tenantInfoService.findById(id);
        Map<String, Object> params = new HashMap<>();
        params.put("moduleId", t.getTenantId());
        params.put("moduleCode", CommonConstants.ResourceInfo_PIC_Org_Certificate);
        ResourceInfo orgPic = resourceInfoService.findFirst(params);

        params = new HashMap<>();
        params.put("userId", t.getTenantId());
        params.put("moduleId", t.getTenantId());
        params.put("moduleCode", CommonConstants.ResourceInfo_PIC_Certificate);
        List<ResourceInfo> resourceInfoList = resourceInfoService.query(params);
        ConfInfo c;
        ResourceInfoVo vr;
        Map<Long, ResourceInfoVo> resourceInfoVoMap = new HashMap<>();
        if (resourceInfoList != null && resourceInfoList.size() > 0) {
            List<TenantCertiInfo> tenantCertiInfoList;
            params = new HashMap<>();
            for (ResourceInfo r : resourceInfoList) {
                params.put("tenantId", t.getTenantId());
                params.put("resourceId", r.getId());
                tenantCertiInfoList = tenantCertiInfoService.query(params);
                if (tenantCertiInfoList != null && tenantCertiInfoList.size() > 0) {
                    for (TenantCertiInfo o : tenantCertiInfoList) {
                        if (resourceInfoVoMap.containsKey(r.getId())) {
                            resourceInfoVoMap.get(r.getId()).getCertiItems().add(o.getConfId());
                            resourceInfoVoMap.get(r.getId()).getCertiItemNames().add(o.getCertiName());
                        } else {
                            vr = new ResourceInfoVo();
                            BeanUtils.copyProperties(r, vr);
                            vr.getCertiItems().add(o.getConfId());
                            vr.getCertiItemNames().add(o.getCertiName());
                            resourceInfoVoMap.put(r.getId(), vr);
                        }
                    }
                }
            }
        }
        return R.ok().put("t", t).put("orgPic", orgPic).
                put("resourceInfos", new ArrayList<>(resourceInfoVoMap.values())).put("remoteUrl", remoteUrl);
    }


    /**
     * 根据ID获取数据
     */
    @RequestMapping("/justInfo/{id}")
    @RequiresPermissions("tenant:tenantInfo:info")
    public R justInfo(@PathVariable("id") Long id) {
        if (id == null || id == 0) {
            id = ShiroUtils.getUserEntity().getDeptId();
        }
        TenantInfo t = tenantInfoService.findById(id);
        return R.ok().put("t", t);
    }


    /**
     * 检验是否已经完善信息
     */
    @RequestMapping("/check")
    public R check() {
        UserInfo u = ShiroUtils.getUserEntity();
        boolean isOk = true;
        if (u.getId() != CommonConstants.SUPER_ADMIN) {
            TenantInfo t = tenantInfoService.findById(ShiroUtils.getUserEntity().getDeptId());
            if (t == null || t.getStatus() == null || t.getStatus().intValue() < CommonConstants.CommonStatus.ENABLE) {
                isOk = false;
            }
        }

        return R.ok().put("isOk", isOk);
    }


    /**
     * 根据ID获取数据
     */
    @RequestMapping("/getCertiTree")
    @RequiresPermissions("tenant:tenantInfo:info")
    public List<ConfInfoVo> getCertiTree(String type) {
        List<ConfInfoVo> confInfoList = new ArrayList<>();
        if (StringUtils.isNotBlank(type)) {
            getCertiListPro(type, null, confInfoList);
        }
        return confInfoList;
    }


    /**
     * 根据ID获取数据
     */
    @RequestMapping("/getCertiType")
    @RequiresPermissions("tenant:tenantInfo:info")
    public List<ConfInfo> getCertiType() {
        Map<String, Object> params = new HashMap<>();
        params.put("type", CommonConstants.CONF_CONSTRUCTION_GRADE_TYPE);
        List<ConfInfo> confInfoList = confInfoService.query(params);
        return confInfoList;
    }


    /**
     * 根据ID获取数据
     */
    @RequestMapping("/getConfInfos")
    @RequiresPermissions("tenant:tenantInfo:info")
    public List<ConfInfo> getConfInfos(String type) {
        List<ConfInfo> confInfoList = new ArrayList<>();
        if (StringUtils.isNotBlank(type)) {
            Map<String, Object> params = new HashMap<>();
            params.put("type", type);
            confInfoList = confInfoService.query(params);
        }

        return confInfoList;
    }


    /**
     * 递归获取配置信息
     *
     * @param type
     * @param confInfoList
     */
    private void getCertiListPro(String type, ConfInfoVo vo, List<ConfInfoVo> confInfoList) {
        Map<String, Object> params = new HashMap<>();
        params.put("type", type);
        List<ConfInfo> confInfos = confInfoService.query(params);
        if (confInfos != null && confInfos.size() > 0) {
            for (ConfInfo c : confInfos) {
                ConfInfoVo _vo = new ConfInfoVo();
                BeanUtils.copyProperties(c, _vo);
                getCertiListPro(_vo.getName(), _vo, confInfoList);
            }
        } else {
            if (StringUtils.isNotBlank(vo.getValue()) && !vo.getValue().equals("none")) {
                appendGrade(vo.getValue(), vo, confInfoList);
            } else {
                vo.setName(vo.getType() + "(" + vo.getName() + ")");
                vo.setCode(vo.getId() + "");
                confInfoList.add(vo);
            }
        }
    }


    /**
     * 拼接等级
     *
     * @param type
     * @param confInfoList
     */
    private void appendGrade(String type, ConfInfoVo vo, List<ConfInfoVo> confInfoList) {
        Map<String, Object> params = new HashMap<>();
        params.put("type", type);
        List<ConfInfo> confInfos = confInfoService.query(params);
        if (confInfos != null && confInfos.size() > 0) {
            ConfInfoVo _vo;
            for (ConfInfo c : confInfos) {
                _vo = new ConfInfoVo();
                BeanUtils.copyProperties(vo, _vo);
                _vo.setCode(vo.getId() + "_" + c.getId());
                _vo.setName(vo.getType() + "(" + vo.getName() + ")" + c.getName());
                confInfoList.add(_vo);
            }
        } else {
            vo.setName(vo.getType() + "(" + vo.getName() + ")");
            vo.setCode(vo.getId() + "");
            confInfoList.add(vo);
        }
    }


    /**
     * 保存
     */
    @SysLog("保存租户信息")
    @RequestMapping("/save")
    @RequiresPermissions("tenant:tenantInfo:save")
    public R save(@RequestBody TenantInfo tenantInfo) {
        tenantInfoService.save(tenantInfo);
        return R.ok();
    }


    /**
     * 修改
     */
    @SysLog("修改租户信息")
    @RequestMapping("/update")
    @RequiresPermissions("tenant:tenantInfo:update")
    public R update(@RequestBody TenantInfoVo tenantInfo) {
        if (ObjectUtil.isNull(tenantInfo.getTenantId())) {
            tenantInfo.setTenantId(ShiroUtils.getUserEntity().getDeptId());
        }
        TenantInfo t = tenantInfoService.findById(tenantInfo.getTenantId());
        Map<String, Object> params = new HashMap<>();
        params.put("deptId", t.getTenantId());
        params.put("deptName", t.getTenantName());
        params.put("type", CommonConstants.UserInfoType.TENANT_ADMIN);
        List<UserInfo> userInfoList = userInfoService.queryByOrgNameAndUseNameAndType(params);
        boolean isEdit = true;
        if (CollectionUtils.isNotEmpty(userInfoList)) {
            isEdit = false;
        } else if (StringUtils.isNotBlank(tenantInfo.getCode())) {
            String proCode = (String) redisTemplate.opsForValue().get(tenantInfo.getBusinessEntityMobile());

            if (StringUtils.isBlank(proCode)) {
                return R.error("验证码已失效");
            }

            if (!proCode.equals(tenantInfo.getCode())) {
                return R.error("短信验证码不正确");
            }

            if (StringUtils.isBlank(tenantInfo.getPassword())) {
                return R.error("请输入密码");
            }

            if (tenantInfo.getBusinessEntityMobile().equals(ShiroUtils.getUserEntity().getName())) {
                return R.error("手机号已被注册");
            }
        }

        tenantInfoService.update(tenantInfo, isEdit);
        return R.ok();
    }


    /**
     * 删除
     */
    @SysLog("删除租户信息")
    @RequestMapping("/delete")
    @RequiresPermissions("tenant:tenantInfo:delete")
    public R delete(@RequestBody Long[] ids) {
        tenantInfoService.deleteBatch(ids);
        return R.ok();
    }


    /**
     * 上传
     */
    @RequestMapping("/import")
    @RequiresPermissions("tenant:tenantInfo:list")
    public R export(MultipartFile file, HttpServletResponse response) {

        UserInfo u = ShiroUtils.getUserEntity();
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }

        IdWorker id = new IdWorker(2);
        String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        File videoFilePath = new File(othersPath);
        if (!videoFilePath.exists()) {
            videoFilePath.mkdirs();
        }

        List<OrgInfoExcel> unCheckedList = new ArrayList<>();
        if (fileType.toUpperCase().endsWith("XLS") || fileType.toUpperCase().endsWith("XLSX")) {
            String filePath = othersPath + File.separator + id.nextId() + fileType;

            try {
                file.transferTo(new File(filePath));
            } catch (IOException e) {
                e.printStackTrace();
            }

            Map<String, ImportSheetParams> sheetClassParamsMap = new HashMap<>();
            Map<String, Object> excel2Map;
            sheetClassParamsMap.put("Sheet1", new ImportSheetParams("orgInfoExcel", 1, 1, new String[]{"企业全称", "纳税人识别号", "联系人", "联系电话"}, OrgInfoExcel.class));
            try {
                excel2Map = ExcelImportUtil.importExcel2Map(new File(filePath), sheetClassParamsMap, null);
            } catch (Exception e) {
                return R.error(e.getMessage());
            }
            List<OrgInfoExcel> dealInfoExcelList = (List<OrgInfoExcel>) excel2Map.get("Sheet1");
            Map<String, Object> params = new HashMap<>();
            if (dealInfoExcelList != null && dealInfoExcelList.size() > 0) {
                List<TenantInfo> tenantInfoList;
                for (OrgInfoExcel e : dealInfoExcelList) {
                    if (StringUtils.isBlank(e.getCertificateCode())) {
                        e.setInfo("社会信用统一代码不能为空");
                        unCheckedList.add(e);
                        continue;
                    }

                    params.put("certificateCode", e.getCertificateCode());
                    tenantInfoList = tenantInfoService.query(params);
                    if (CollectionUtils.isNotEmpty(tenantInfoList)) {
                        e.setInfo("社会信用统一代码已经存在");
                        unCheckedList.add(e);
                        continue;
                    }
                    if (StringUtils.isBlank(e.getContactPerson())) {
                        e.setInfo("联系人不能为空");
                        unCheckedList.add(e);
                        continue;
                    }

                    if (StringUtils.isBlank(e.getContactPersonMoble()) || e.getContactPersonMoble().length() != 11) {
                        e.setInfo("联系人手机号不能为空");
                        unCheckedList.add(e);
                        continue;
                    }

                    tenantInfoService.save(new SysRegisterForm(e.getOrgName(), e.getCertificateCode(), e.getContactPerson(), e.getContactPersonMoble(), e.getContactPersonMoble().substring(5)));
                }
            }
        } else {
            return R.error("请上传 Excel 文件！");
        }

        if (unCheckedList.size() > 0) {
            try {
                List<OrgInfoExportExcel> dealInfoExportExcelList = new ArrayList<>();
                OrgInfoExportExcel o;
                for (OrgInfoExcel vo : unCheckedList) {
                    o = new OrgInfoExportExcel();
                    BeanUtils.copyProperties(vo, o);
                    dealInfoExportExcelList.add(o);
                }
                ExcelUtils.exportExcel(dealInfoExportExcelList, "租户信息未导入成功统计", "Sheet1", OrgInfoExportExcel.class, "租户信息未导入成功统计.xls", response);
            } catch (Exception e) {
                return R.error(e.getMessage());
            }
        }

        return R.ok();
    }


    /**
     * 上传
     */
    @RequestMapping("/upload")
    @RequiresPermissions("tenant:tenantInfo:update")
    public R upload(MultipartFile file) {

        IdWorker id = new IdWorker(2);
        if (file.isEmpty()) {
            return R.error("上传文件不能为空");
        }

        String fileName = id.nextId() + "";
        try {
            fileName = FileUtils.transform(file, picPath, fileName, 2, "M", new String[]{FileUtils.JPG, FileUtils.PNG});
        } catch (Exception e) {
            return R.error(e.getMessage());
        }

        return R.ok().put("fileName", fileName).put("remoteUrl", remoteUrl);
    }

}
